package cn.kbyue.logdemo.common;

import ch.qos.logback.classic.pattern.MessageConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import org.apache.commons.lang3.StringUtils;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 日志脱敏过滤器
 */
public class LogSensitiveConverter extends MessageConverter {

    private static final String IDCARD_REGEX = "(\\d{18}|\\d{15}|\\d{17}x)";
    private static final String KEY = "axedfqLGpu";

    public static void main(String[] args) {
        System.out.println(LogSensitiveConverter.filterSensitive("18711112222"));
        System.out.println(LogSensitiveConverter.filterSensitive("500298233472819110"));
        System.out.println(LogSensitiveConverter.decrypt("5002upeddfGepx9110", 4, 4));
    }

    @Override
    public String convert(ILoggingEvent event) {
        String logMessage = event.getFormattedMessage();
        return filterSensitive(logMessage);
    }

    /**
     * 对敏感信息脱敏
     */
    private static String filterSensitive(String content) {
        try {
            if (StringUtils.isBlank(content)) {
                return content;
            }
            content = desensitizeIdCard(content);
            content = desensitizePhoneNumber(content);
            return content;
        } catch (Exception e) {
            return content;
        }
    }

    /**
     * 身份证号脱敏, 简单版本
     */
    public static String desensitizeIdCard(String idCard) {
        if (idCard == null || idCard.length() < 18) {
            return idCard;
        }
        Pattern pattern = Pattern.compile(IDCARD_REGEX);
        Matcher matcher = pattern.matcher(idCard);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, baseSensitive(matcher.group(), 4, 4));
        }
        // sb.append(idCard.substring(idCard.length() - 4));
        matcher.appendTail(sb);
        return sb.toString();
    }

    /**
     * 手机号码脱敏, 简单版本
     */
    public static String desensitizePhoneNumber(String phoneNumber) {
        if (phoneNumber == null || phoneNumber.length() < 11) {
            return phoneNumber;
        }
        return phoneNumber.replaceAll("(\\d{3})\\d{4}(\\d+)", "$1****$2");
    }

    /**
     * 基础脱敏处理 指定起止展示长度 剩余用"KEY"中字符替换
     *
     * @param str         待脱敏的字符串
     * @param startLength 开始展示长度
     * @param endLength   末尾展示长度
     * @return 脱敏后的字符串
     */
    private static String baseSensitive(String str, int startLength, int endLength) {
        if (StringUtils.isBlank(str)) {
            return "";
        }
        String replacement = str.substring(startLength, str.length() - endLength);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < replacement.length(); i++) {
            char ch;
            if (replacement.charAt(i) >= '0' && replacement.charAt(i) <= '9') {
                ch = KEY.charAt(replacement.charAt(i) - '0');
            } else {
                ch = replacement.charAt(i);
            }
            sb.append(ch);
        }
        return StringUtils.left(str, startLength).concat(StringUtils.leftPad(StringUtils.right(str, endLength), str.length() - startLength, sb.toString()));
    }

    /**
     * 按"KEY"中字符解密
     */
    private static String decrypt(String str, int startLength, int endLength) {
        if (StringUtils.isBlank(str)) {
            return "";
        }
        String replacement = str.substring(startLength, str.length() - endLength);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < replacement.length(); i++) {
            int index = KEY.indexOf(replacement.charAt(i));
            if (index != -1) {
                sb.append(index);
            } else {
                sb.append(replacement.charAt(i));
            }
        }
        return StringUtils.left(str, startLength).concat(StringUtils.leftPad(StringUtils.right(str, endLength), str.length() - startLength, sb.toString()));
    }
}
